package com.bong.panpan.bongcharttools.util.csvutil;

import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.hardware.usb.UsbDevice;
import android.hardware.usb.UsbManager;
import android.os.Handler;
import android.text.TextUtils;
import android.util.Log;

import com.github.mjdev.libaums.UsbMassStorageDevice;
import com.github.mjdev.libaums.fs.FileSystem;
import com.github.mjdev.libaums.fs.UsbFile;
import com.github.mjdev.libaums.fs.UsbFileInputStream;
import com.github.mjdev.libaums.partition.Partition;

import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;


/**
 * Created by hackill on 2018/1/8.
 */

public class UsbHelper {
    private static final String TAG = "UsbHelper";

    //自定义U盘读写权限
    public static final String ACTION_USB_PERMISSION = "com.android.bong.USB_PERMISSION";
    private Context context;

    //U盘列表
    private UsbMassStorageDevice[] storageDevices;
    //当前U盘所在文件目录
    private UsbFile cFolder;
    //u盘相关操作监听
    private OnUsbOperateListener onUsbOperateListener;

    private Handler handler = new Handler();

    public UsbHelper(Context context) {
        this.context = context;
    }

    public void setOnUsbOperateListener(OnUsbOperateListener onUsbOperateListener) {
        this.onUsbOperateListener = onUsbOperateListener;
    }

    Runnable resumeRun = new Runnable() {
        @Override
        public void run() {
            registerUDiskReceiver();
            init();
        }
    };
    Runnable pauseRun = new Runnable() {
        @Override
        public void run() {
            unregisterUDiskReceiver();
        }
    };

    public void onResume() {
        handler.removeCallbacks(pauseRun);
        handler.postDelayed(resumeRun, 500);
    }

    public void onPause() {
        handler.removeCallbacks(resumeRun);
        handler.postDelayed(pauseRun, 500);
    }
    public void onDestory() {
        handler.removeCallbacks(resumeRun);
        pauseRun.run();
    }
    /**
     * 初始化设备 防止在程序启动前 u盘就已经插入
     */
    public void init() {
        if (FileUtils.isExistUsbDevice(context)) {
            prepareUsbDevice();
        }
    }

    /**
     * 保存文件到USB
     *
     * @param filePath
     */
    public void saveFileToUsb(String filePath) throws IOException {
        saveFileToUsb(new File(filePath));
    }

    /**
     * 保存文件到USB
     *
     * @param filePath
     */
    public void saveFileToUsb(File file) throws IOException {
        FileUtils.saveSDFile2OTG(file, cFolder);
    }

    /**
     * 保存文件到USB
     *
     * @param filePath
     */
    public void saveFileToUsb(File file, String path) throws IOException {
        UsbFile file1 = cFolder.search(path);
        if (file1 == null)
            file1 = cFolder.createDirectory(path);
        FileUtils.saveSDFile2OTG(file, file1);
    }

    /**
     * 从USB上读取文件
     *
     * @param fileName
     */
    public List<String> readFileFromUsb(String fileName) throws IOException {

        UsbFile[] usbFiles = cFolder.listFiles();

        if (null != usbFiles && usbFiles.length > 0) {
            for (UsbFile usbFile : usbFiles) {
                if (usbFile.getName().equals(fileName)) {
                    return readFileFromUsb(usbFile);
                }
            }
        }
        return null;
    }

    private List<String> readFileFromUsb(UsbFile usbFile) throws IOException {

        //读取文件内容
        InputStream is = new UsbFileInputStream(usbFile);

        BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(is));
        String read;
        List<String> lines = new ArrayList<>();
        while ((read = bufferedReader.readLine()) != null) {
            lines.add(read);
        }
        bufferedReader.close();

        return lines;
    }

    /**
     * 监听USB广播
     */
    private void registerUDiskReceiver() {
        //监听otg插入 拔出
        IntentFilter usbDeviceStateFilter = new IntentFilter();
        usbDeviceStateFilter.addAction(UsbManager.ACTION_USB_DEVICE_ATTACHED);
        usbDeviceStateFilter.addAction(UsbManager.ACTION_USB_DEVICE_DETACHED);
        //添加自定义广播
        usbDeviceStateFilter.addAction(ACTION_USB_PERMISSION);
        context.registerReceiver(mOtgReceiver, usbDeviceStateFilter);
    }

    /**
     * 取消监听
     */
    private void unregisterUDiskReceiver() {
        try {
            context.unregisterReceiver(mOtgReceiver);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private BroadcastReceiver mOtgReceiver = new BroadcastReceiver() {
        public void onReceive(Context context, Intent intent) {
            String action = intent.getAction();
            if (TextUtils.equals(ACTION_USB_PERMISSION, action)) {
                Log.i(TAG, "onReceive: 读取权限通知");
                //允许权限申请
                if (intent.getBooleanExtra(UsbManager.EXTRA_PERMISSION_GRANTED, false)) {
                    onUsbOperateListener.onPermissionGranted();
                    UsbDevice usbDevice = intent.getParcelableExtra(UsbManager.EXTRA_DEVICE);
                    if (usbDevice != null) {
                        //用户已授权，可以进行读取操作
                        readDevice(getUsbMass(usbDevice));
                    } else {
                        onUsbOperateListener.unrecognized();
                    }
                } else {
                    onUsbOperateListener.onPermissionCancel();
                }
            } else if (TextUtils.equals(UsbManager.ACTION_USB_DEVICE_ATTACHED, action)) {
                Log.i(TAG, "onReceive: 插入U盘");
                onUsbOperateListener.onInsert();

                if (intent.getParcelableExtra(UsbManager.EXTRA_DEVICE) != null) {
                    //准备设备列表
                    init();
                } else {
                    onUsbOperateListener.unrecognized();
                }

            } else if (TextUtils.equals(UsbManager.ACTION_USB_DEVICE_DETACHED, action)) {
                Log.i(TAG, "onReceive: U盘已拔出 ");
                onUsbOperateListener.onPullOut();
            }
        }
    };

    /**
     * @description U盘设备读取
     * @author ldm
     * @time 2017/9/1 17:20
     */
    private void prepareUsbDevice() {

        //获取U盘存储设备
        storageDevices = UsbMassStorageDevice.getMassStorageDevices(context);
        //设备管理器
        UsbManager usbManager = (UsbManager) context.getSystemService(Context.USB_SERVICE);

        if (usbManager == null || storageDevices.length == 0) {
            onUsbOperateListener.unrecognized();
            return;
        }
        //取出第一个U盘
        UsbMassStorageDevice device = storageDevices[0];

        //判断是否有操作权限
        if (usbManager.hasPermission(device.getUsbDevice())) {
            readDevice(device);
        } else {
            //没有权限，进行申请
            PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, new Intent(ACTION_USB_PERMISSION), 0);
            usbManager.requestPermission(device.getUsbDevice(), pendingIntent);
        }
    }

    private UsbMassStorageDevice getUsbMass(UsbDevice usbDevice) {
        for (UsbMassStorageDevice device : storageDevices) {

            if (usbDevice.equals(device.getUsbDevice())) {
                return device;
            }
        }
        return null;
    }

    private void readDevice(UsbMassStorageDevice device) {
        try {
            device.init();//初始化
            //设备分区
            Partition partition = device.getPartitions().get(0);
            //文件系统
            FileSystem currentFs = partition.getFileSystem();
            currentFs.getVolumeLabel();//可以获取到设备的标识
            //通过FileSystem可以获取当前U盘的一些存储信息，包括剩余空间大小，容量等等
            Log.e("Capacity: ", currentFs.getCapacity() + "");
            Log.e("Occupied Space: ", currentFs.getOccupiedSpace() + "");
            Log.e("Free Space: ", currentFs.getFreeSpace() + "");
            Log.e("Chunk size: ", currentFs.getChunkSize() + "");
            cFolder = currentFs.getRootDirectory();//设置当前文件对象为根目录
        } catch (Exception e) {
            e.printStackTrace();
            onUsbOperateListener.unrecognized();
        }
    }


    public interface OnUsbOperateListener {

        /**
         * U盘 插入
         */
        void onInsert();

        /**
         * U盘 已拔出
         */
        void onPullOut();

        /**
         * U盘 无法识别
         */
        void unrecognized();

        /**
         * 发起读取U盘权限 被用户取消
         */
        void onPermissionCancel();

        /**
         * 发起读取U盘权限 被用户允许操作
         */
        void onPermissionGranted();
    }
}

